package com.wonder.app.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.StkApplyDao;
import com.wonder.app.mapper.StkApplyDetailDao;
import com.wonder.app.service.StkApplyDetailService;
import com.wonder.app.service.StkApplyService;
import com.wonder.app.service.StkotheroutService;
import com.wonder.app.service.SyncKingdeeOrderService;
import com.wonder.bean.kingdee.VtuzxKingdeeCloudClient;
import com.wonder.constant.BillType;
import com.wonder.constant.KingdeeServiceKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class StkApplyServiceImpl  extends ServiceImpl<StkApplyDao, StkApply> implements StkApplyService {
    /** 日志 */
    private static final Logger _logger = LoggerFactory.getLogger(StkApplyServiceImpl.class);

    @Autowired
    private StkApplyDao stkApplyDao;

    @Autowired
    private StkApplyService stkApplyService;

    @Autowired
    private SyncKingdeeOrderService syncKingdeeOrderService;

    @Autowired
    private StkApplyDetailDao stkApplyDetailDao;


    @Autowired
    private StkApplyDetailService stkApplyDetailService;

    @Autowired
    private StkotheroutService stkotheroutService;


    /**
     * 金蝶审核其他出库申请单
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public boolean audit(JSONObject map) throws Exception {
        _logger.info("审核其他出库申请单"+ map.toString());
        JSONArray applyList = map.getJSONArray("ApplyList");
        JSONObject applyObj = (JSONObject) applyList.get(0);
        JSONArray head = applyObj.getJSONArray("model");//单据头数据
        JSONArray detailList = applyObj.getJSONArray("detail");//单据体数据、
        List<StkApply> stkapplyList = new ArrayList<>();//添加到单据头的数据
        List<StkApplyDetail> stkApplyDetailList = new ArrayList<>();//添加到单据体的数据
        List<Long> fidList = new ArrayList<>();//单据头需要删除的fid集合
        List<Long> entryIdList = new ArrayList<>();//单据体需要删除的entryid集合
        for (Object obj : head) {
            JSONObject jsonObject = (JSONObject) obj;
            //将json直接转成实体类
            StkApply stkApply = jsonObject.toBean(StkApply.class);
            stkApply.setSTATUS("save");
            Long fid = stkApply.getFID();
            if (!fidList.contains(fid)){
                fidList.add(fid);
            }

            stkapplyList.add(stkApply);
        }
        //单据体数据
        for (Object obj : detailList) {
            JSONObject jsonObject = (JSONObject) obj;
            //将json直接转成实体类
            StkApplyDetail stkApplyDetail = jsonObject.toBean(StkApplyDetail.class);
            Long entryId = stkApplyDetail.getFENTRYID();
            stkApplyDetail.setCLOSTSTATUS(0);
            if (!entryIdList.contains(entryId)){
                entryIdList.add(entryId);
            }
            stkApplyDetailList.add(stkApplyDetail);
        }


        //查询有没有需要删除的单据
        List<StkApply> applyDelete =  stkApplyDao.selectList(new LambdaQueryWrapper<StkApply>()
                .in(StkApply::getFID,fidList));
        if (null != applyDelete || applyDelete.size() > 0){
            stkApplyDao.delete(new LambdaQueryWrapper<StkApply>()
                    .in(StkApply::getFID,fidList));

        }
        List<StkApplyDetail> receivedetails =  stkApplyDetailDao.selectList(new LambdaQueryWrapper<StkApplyDetail>()
                .in(StkApplyDetail::getFENTRYID,entryIdList));
        if (null != receivedetails || receivedetails.size() > 0){
            stkApplyDetailDao.delete(new LambdaQueryWrapper<StkApplyDetail>()
                    .in(StkApplyDetail::getFENTRYID,entryIdList));

        }
        //向数据库添加数据
        boolean resHead = stkApplyService.saveOrUpdateBatch(stkapplyList);
        boolean res = stkApplyDetailService.saveOrUpdateBatch(stkApplyDetailList);
        return res && resHead;
    }

    /**
     * 出库申请手机端列表
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> getStkApplyList(Map<String, Object> map) {
        int pageIndex = VtuzxUtil.getInt(map,"pageIndex");
        int pageSize = VtuzxUtil.getInt(map,"pageSize");
        String billNo = VtuzxUtil.getString(map,"billNo");//订单号
        //直接查询明细展示明细信息
        List<StkApplyDetail> dataList = stkApplyDetailDao.getStkApplyList(pageSize,pageIndex * pageSize,billNo);
        Map<String,Object> data = new HashMap<>();
        data.put("dataList",dataList);
        return data;
    }

    /**
     * 出库申请单详情
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> getStkApplyDetail(Map<String, Object> map) {
        Long detailId = VtuzxUtil.getLong(map,"detailId");
        //通过fid查询详情数据
        StkApplyDetail stkApplyDetail = stkApplyDetailDao.selectById(detailId);
        Long fid = stkApplyDetail.getFID();
        StkApply stkApply = stkApplyDao.selectOne(new LambdaQueryWrapper<StkApply>()
                .eq(StkApply::getFID,fid));
        Map<String,Object> data = new HashMap<>();
        data.put("data",stkApply);
        data.put("dataList",stkApplyDetail);
        return data;
    }

    /**
     * 审核其他出库申请单
     * @param user_id
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public Boolean auditStkApply(String userName, Long user_id, Map<String, Object> map) throws Exception {
        //先保存仓位信息,然后生成其他出库单
        String billNo = VtuzxUtil.getString(map,"billNo");
        Long fid = VtuzxUtil.getLong(map,"fid");//单据头fid
        StkApply stkApply = stkApplyDao.selectOne(new LambdaQueryWrapper<StkApply>()
                .eq(StkApply::getFID, fid));
        Map<String,Object> detailList = VtuzxUtil.getObject(map,"dataList");//出库申请明细
        List<StkApplyDetail> stkApplyDetailList = stkApplyDetailDao.selectList(new LambdaQueryWrapper<StkApplyDetail>()
                .eq(StkApplyDetail::getFID, fid));
        Map<String,Object> dataMap = new HashMap<>();//key:id.val:仓库，仓位
//        for (Map<String,Object> data : detailList){
            Integer detailId = VtuzxUtil.getInt(detailList,"id");
            String flocationno = VtuzxUtil.getString(detailList,"flocationno");
            Map<String,Object> stockMap1 =new HashMap<>();
            stockMap1.put("flocationno",flocationno);
            dataMap.put( detailId.toString(),stockMap1);
//        }

        //数据库添加仓位信息
        for (StkApplyDetail stkApplyDetail : stkApplyDetailList){
            Long id = stkApplyDetail.getId();
            Map<String,Object> stockMap = VtuzxUtil.getObject(dataMap, id.toString());
            if (!VtuzxUtil.isEmpty(stockMap)){
                String locationNo = VtuzxUtil.getString(stockMap,"flocationno");
                stkApplyDetail.setFLOCATIONNO(locationNo);
            }

        }
        stkApplyDetailService.saveOrUpdateBatch(stkApplyDetailList);
        //增加其他出库申请单
        Boolean otherOut = stkotheroutService.createOtherOut(user_id, userName, stkApply, detailList);
        //修改申请单状态为审核
        stkApply.setSTATUS("audit");
        stkApplyService.updateById(stkApply);

        return otherOut;
    }

    /**
     * 推荐仓位，根据物料查询库存信息
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> commendLocation(Long user_id, Map<String, Object> map) throws Exception {
        String materialNo = VtuzxUtil.getString(map,"materialNo");
        Map<String, Object> data = syncKingdeeOrderService.getInventoryByNo(user_id,materialNo);
        return data;
    }


    /**
     * 根据件号和仓库查询库存
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> commendLocationByItem(Long user_id, Map<String, Object> map) throws Exception {
//        String materialNo = VtuzxUtil.getString(map,"materialNo");
        Map<String, Object> data = syncKingdeeOrderService.getInventoryByItem(user_id,map);
        return data;
    }


    /**
     * 出库申请整单关闭
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public boolean applyClose(JSONObject map) throws Exception {
        _logger.info("出库申请整单关闭:"+map.toString());
        JSONArray detailList = map.getJSONArray("applyCloseList");
//        JSONObject applyObj = (JSONObject) applyJson.get(0);
//        JSONArray detailList = applyObj.getJSONArray("applyCloseList");//关闭数据
        boolean first= true;
        boolean resDetail = false;
        for (Object obj : detailList) {
            JSONObject item = (JSONObject) obj;
            String applyBillNo = item.getStr("FBILLNO");//单据编号
            int FID  = item.getInt("FID");//单据内码
            String FCLOSESTATUS = item.getStr("FCLOSESTATUS");//单据头关闭状态A正常B关闭
            String FBUSINESSCLOSED = item.getStr("FBUSINESSCLOSED");//业务关闭状态A正常B业务关闭
            String FBUSINESSEND= item.getStr("FBUSINESSEND");//业务终止
            int FENTRYID = item.getInt("FENTRYID");//单据体内码
            if (first && FCLOSESTATUS.equals("B")){//第一行整单关闭的话单据头单据体都直接修改
                StkApply stkApply = stkApplyDao.selectOne(new LambdaQueryWrapper<StkApply>()
                        .eq(StkApply::getFBILLNO,applyBillNo));
                if (null == stkApply){
                    throw new RuntimeException(String.format("未查询到数据单号%s", applyBillNo));
                }
                stkApply.setCLOSTSTATUS(1);
                List<StkApplyDetail> stkApplyDetailList = stkApplyDetailDao.selectList(new LambdaQueryWrapper<StkApplyDetail>()
                        .eq(StkApplyDetail::getFID,FID));
                for (StkApplyDetail stkApplyDetail : stkApplyDetailList){
                    stkApplyDetail.setCLOSTSTATUS(1);
                }
                boolean reshead = stkApplyService.saveOrUpdate(stkApply);
                resDetail = stkApplyDetailService.saveOrUpdateBatch(stkApplyDetailList);
            }else{//每行单据状态关闭都改
                if (FBUSINESSCLOSED.equals("B") || FBUSINESSEND.equals("B")) {
                    StkApplyDetail stkApplyDetail = stkApplyDetailDao.selectOne(new LambdaQueryWrapper<StkApplyDetail>()
                            .eq(StkApplyDetail::getFENTRYID,FENTRYID));
                    if (null == stkApplyDetail){
                        throw new RuntimeException(String.format("未查询到数据单号%s", applyBillNo));
                    }
                    stkApplyDetail.setCLOSTSTATUS(1);
                    resDetail = stkApplyDetailService.saveOrUpdate(stkApplyDetail);
                }

            }
            first = false;
        }
        return resDetail;
    }

    /**
     * 出库申请单反审核
     * @param map
     * @return
     * @throws Exception
     */
    public boolean unAudit(JSONObject map) throws Exception {
        _logger.info("出库申请单反审核:"+map.toString());
        JSONArray detailList = map.getJSONArray("applyList");
        List<Long> billNoList = detailList.toList(long.class);
        //批量删除多行数据
        boolean remove = stkApplyService.remove(new LambdaQueryWrapper<StkApply>()
                .in(StkApply::getFID,billNoList));
        boolean detailRes = stkApplyDetailService.remove(new LambdaQueryWrapper<StkApplyDetail>()
                .in(StkApplyDetail::getFID,billNoList));
        return remove && detailRes;
    }


}
